package com.anji.hyperneat.onlinereinforcement.trainingbank;

import com.anji.hyperneat.nd.NDFloatArray;
import com.anji.hyperneat.nd.NDFloatArray.MatrixIterator;
import com.anji.hyperneat.onlinereinforcement.IOnlineLearningActivatorND;

public class TrainingSample {

	public NDFloatArray input;
	public Feedback feedback;
	public float weight;
	public IOnlineLearningActivatorND linkedNet;
	
	public TrainingSample() {}
	
	public TrainingSample(NDFloatArray input, Feedback feedback, float weight, IOnlineLearningActivatorND linkedNet) {
		this.input = input;
		this.feedback = feedback;
		this.weight = weight;
		this.linkedNet = linkedNet;
	}
	
	public void applyToNet() {
		linkedNet.next(input);
		linkedNet.updateNet(feedback.value, weight);
	}
		
	public float applyToNetAndGetSqErr() {
		linkedNet.next(input);
		float err = calculateSqErr(linkedNet.getOutputs(), feedback.value);
		linkedNet.updateNet(feedback.value, weight);
		return err;
	}
	
	private float calculateSqErr(NDFloatArray outputs, NDFloatArray expectedOuts) {
		float total = 0;
		for (MatrixIterator expecteds = expectedOuts.iterator(); expecteds.hasNext(); expecteds.next()) {
			total += (float) Math.pow(expecteds.get() - outputs.getFromRawCoordinate(expecteds.getRawCoordinate()), 2);
		}
		return total;
	}

	public String toString() {
		return feedback.toString() + "\nweight:" + weight;
	}
}
